/***********************************
 * 客户端上传文件
 *
 * 成功返回1，失败返回-1
 ***********************************/

#include "../include/client.h"

int clientUpload(int sockFd, char *fileName){

    //告诉服务器要自己要上传文件了
    char buf[128] = {0};
    memcpy(buf, "upload", 6);
    
    //先open一下文件，看要上传的文件是否存在，如果不存在直接返回
    int ret = open(fileName, O_RDONLY, 0);
    if(ret == -1){
        printf("don't find %s!\n", fileName);
        return -1;
    }

    char flag;
    ret = send(sockFd, buf, 128, 0);

    //1、生成文件对应的MD5码，为了提高效率，根据文件的前500B来生成
    char md5str[MD5_STR_LEN + 1] = {0};
    Train_t train;  //传输用的小火车
    memset(&train, 0, sizeof(train));

    ret = Compute_file_md5(fileName, md5str);
    if(0 == ret){
        printf("[file - %s] md5 value:\n", fileName);
        printf("%s\n", md5str);
    }

    //2、把文件的信息发送给服务器
    
    //   (1)发送文件名
    train.dataLen = strlen(fileName);
    memcpy(train.buf, fileName, train.dataLen);
    send(sockFd, &train, 4+train.dataLen, 0);

    //   (2)发送文件MD5码，接收服务器的反馈
    memset(&train, 0, sizeof(train));
    train.dataLen = strlen(md5str);
    memcpy(train.buf, md5str, train.dataLen);
    send(sockFd, &train, 4+train.dataLen, 0);
    //接收反馈
    recv(sockFd, &flag, 1, 0);

    //如果要上传的同名文件，结束上传
    if(flag == 'e'){
        printf("file already exists!\n");
        return 1;
    }
    
    //如果文件在服务器上已经存在，完成秒传
    if(flag == 'a'){
        //获取文件的大小
        struct stat sstat;
        stat(fileName, &sstat);
        int fileSize = (int)sstat.st_size;
        //发送文件的大小
        memset(&train, 0, sizeof(train));
        train.dataLen = sizeof(fileSize);
        memcpy(train.buf, &fileSize, train.dataLen);
        send(sockFd, &train, 4+train.dataLen, 0);
        printf("upload successful!\n");
        return 1;
    }

    //   (3)发送文件大小
    //获取文件的大小
    struct stat sstat;
    stat(fileName, &sstat);
    int fileSize = (int)sstat.st_size;
    //发送文件的大小
    memset(&train, 0, sizeof(train));
    train.dataLen = sizeof(fileSize);
    memcpy(train.buf, &fileSize, train.dataLen);
    send(sockFd, &train, 4+train.dataLen, 0);

    //3、发送文件，接收反馈，看服务器是否成功接收
    sendFile(sockFd, fileName);
    recv(sockFd, &flag, 1, 0);
    while(flag == 'u'){
        //服务器接收失败，重新传输
        printf("send field!\n");
        /* sendFile(sockFd, fileName); */
        /* recv(sockFd, &flag, 1, 0); */
        return -1;
    }
    if(flag == 'a'){
        //发送成功
        printf("upload successful!\n");
        return 1;
    }

    return 1;
}
